home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / mkpasswd / mkpasswd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-07-19  |  6.4 KB  |  250 lines

  1. /*
  2.  * Copyright (c) 1980, 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. char copyright[] =
  20. "@(#) Copyright (c) 1980, 1983 Regents of the University of California.\n\
  21.  All rights reserved.\n";
  22. #endif /* not lint */
  23.  
  24. #ifndef lint
  25. static char sccsid[] = "@(#)mkpasswd.c    5.4 (Berkeley) 2/22/89";
  26. #endif /* not lint */
  27.  
  28. #include <sys/param.h>
  29. #include <sys/file.h>
  30. #ifdef USE_DB
  31. #include <ndbm.h>
  32. #endif
  33. #include <pwd.h>
  34. #include <stdio.h>
  35.  
  36. static FILE *_pw_fp;
  37. static struct passwd _pw_passwd;
  38. static off_t offset;
  39.  
  40. #define    MAXLINELENGTH    1024
  41. static char line[MAXLINELENGTH];
  42.  
  43. /*
  44.  * Mkpasswd does two things -- use the ``arg'' file to create ``arg''.{pag,dir}
  45.  * for ndbm, and, if the -p flag is on, create a password file in the original
  46.  * format.  It doesn't use the getpwent(3) routines because it has to figure
  47.  * out offsets for the encrypted passwords to put in the dbm files.  One other
  48.  * problem is that, since the addition of shadow passwords, getpwent(3) has to
  49.  * use the dbm databases rather than simply scanning the actual file.  This
  50.  * required the addition of a flag field to the dbm database to distinguish
  51.  * between a record keyed by name, and one keyed by uid.
  52.  */
  53.  
  54. main(argc, argv)
  55.     int argc;
  56.     char **argv;
  57. {
  58.     extern int errno, optind;
  59.     register char *flag, *p, *t;
  60.     register int makeold;
  61.     FILE *oldfp;
  62. #ifdef USE_DB
  63.     DBM *dp;
  64.     datum key, content;
  65. #endif
  66.     int ch;
  67.     char buf[8192], nbuf[50], *strerror();
  68.  
  69.     makeold = 0;
  70.     while ((ch = getopt(argc, argv, "pv")) != EOF)
  71.         switch(ch) {
  72.         case 'p':            /* create ``password.orig'' */
  73.             makeold = 1;
  74.             /* FALLTHROUGH */
  75.         case 'v':            /* backward compatible */
  76.             break;
  77.         case '?':
  78.         default:
  79.             usage();
  80.         }
  81.     argc -= optind;
  82.     argv += optind;
  83.  
  84.     if (argc != 1)
  85.         usage();
  86.  
  87.     if (!(_pw_fp = fopen(*argv, "r"))) {
  88.         (void)fprintf(stderr,
  89.             "mkpasswd: %s: can't open for reading.\n", *argv);
  90.         exit(1);
  91.     }
  92.  
  93.     rmall(*argv);
  94.     (void)umask(0);
  95.  
  96.     /* open old password format file, dbm files */
  97.     if (makeold) {
  98.         int oldfd;
  99.  
  100.         (void)sprintf(buf, "%s.orig", *argv);
  101.         if ((oldfd = open(buf, O_WRONLY|O_CREAT|O_EXCL, 0444)) < 0) {
  102.             (void)fprintf(stderr, "mkpasswd: %s: %s\n", buf,
  103.                 strerror(errno));
  104.             exit(1);
  105.         }
  106.         if (!(oldfp = fdopen(oldfd, "w"))) {
  107.             (void)fprintf(stderr, "mkpasswd: %s: fdopen failed.\n",
  108.                 buf);
  109.             exit(1);
  110.         }
  111.     }
  112. #ifdef USE_DB
  113.     if (!(dp = dbm_open(*argv, O_WRONLY|O_CREAT|O_EXCL, 0644))) {
  114.         (void)fprintf(stderr, "mkpasswd: %s: %s\n", *argv,
  115.             strerror(errno));
  116.         exit(1);
  117.     }
  118.  
  119.     content.dptr = buf;
  120. #endif
  121.     while (scanpw()) {
  122. #ifdef USE_DB
  123.         /* create dbm entry */
  124.         p = buf;
  125. #define    COMPACT(e)    t = e; while (*p++ = *t++);
  126.         COMPACT(_pw_passwd.pw_name);
  127.         (void)sprintf(nbuf, "%ld", offset);
  128.         COMPACT(nbuf);
  129.         bcopy((char *)&_pw_passwd.pw_uid, p, sizeof(int));
  130.         p += sizeof(int);
  131.         bcopy((char *)&_pw_passwd.pw_gid, p, sizeof(int));
  132.         p += sizeof(int);
  133.         bcopy((char *)&_pw_passwd.pw_change, p, sizeof(time_t));
  134.         p += sizeof(time_t);
  135.         COMPACT(_pw_passwd.pw_class);
  136.         COMPACT(_pw_passwd.pw_gecos);
  137.         COMPACT(_pw_passwd.pw_dir);
  138.         COMPACT(_pw_passwd.pw_shell);
  139.         bcopy((char *)&_pw_passwd.pw_expire, p, sizeof(time_t));
  140.         p += sizeof(time_t);
  141.         flag = p;
  142.         *p++ = _PW_KEYBYNAME;
  143.         content.dsize = p - buf;
  144. #ifdef debug
  145.         (void)printf("store %s, uid %d\n", _pw_passwd.pw_name,
  146.             _pw_passwd.pw_uid);
  147. #endif
  148.         key.dptr = _pw_passwd.pw_name;
  149.         key.dsize = strlen(_pw_passwd.pw_name);
  150.         if (dbm_store(dp, key, content, DBM_INSERT) < 0)
  151.             goto bad;
  152.         key.dptr = (char *)&_pw_passwd.pw_uid;
  153.         key.dsize = sizeof(int);
  154.         *flag = _PW_KEYBYUID;
  155.         if (dbm_store(dp, key, content, DBM_INSERT) < 0)
  156.             goto bad;
  157. #endif
  158.  
  159.         /* create original format password file entry */
  160.         if (!makeold)
  161.             continue;
  162.         if (strcmp(_pw_passwd.pw_name,"root")) {
  163.         /* shadow */
  164.         fprintf(oldfp, "%s:*:%d:%d:%s:%s:%s\n", _pw_passwd.pw_name,
  165.             _pw_passwd.pw_uid, _pw_passwd.pw_gid, _pw_passwd.pw_gecos,
  166.             _pw_passwd.pw_dir, _pw_passwd.pw_shell);
  167.         } else {
  168.         /* not shadow */
  169.         fprintf(oldfp, "%s:%s:%d:%d:%s:%s:%s\n", _pw_passwd.pw_name,
  170.             _pw_passwd.pw_passwd,
  171.             _pw_passwd.pw_uid, _pw_passwd.pw_gid, _pw_passwd.pw_gecos,
  172.             _pw_passwd.pw_dir, _pw_passwd.pw_shell);
  173.         }
  174.     }
  175. #ifdef USE_DB
  176.     dbm_close(dp);
  177. #endif
  178.     exit(0);
  179.  
  180. bad:    (void)fprintf(stderr, "mkpasswd: dbm_store failed.\n");
  181.     rmall(*argv);
  182.     exit(1);
  183. }
  184.  
  185. rmall(fname)
  186.     char *fname;
  187. {
  188.     register char *p;
  189.     char buf[MAXPATHLEN], *strcpy();
  190.  
  191.     for (p = strcpy(buf, fname); *p; ++p);
  192.     bcopy(".pag", p, 5);
  193.     (void)unlink(buf);
  194.     bcopy(".dir", p, 5);
  195.     (void)unlink(buf);
  196.     bcopy(".orig", p, 6);
  197.     (void)unlink(buf);
  198. }
  199.  
  200. usage()
  201. {
  202.     (void)fprintf(stderr, "usage: mkpasswd [-p] passwd_file\n");
  203.     exit(1);
  204. }
  205.  
  206. /* from libc/gen/getpwent.c */
  207.  
  208. static
  209. scanpw()
  210. {
  211.     register char *cp;
  212.     long atol(), ftell();
  213.     char *fgets(), *strsep(), *index();
  214.  
  215.     for (;;) {
  216.         offset = ftell(_pw_fp);
  217.         if (!(fgets(line, sizeof(line), _pw_fp)))
  218.             return(0);
  219.         /* skip lines that are too big */
  220.         if (!index(line, '\n')) {
  221.             int ch;
  222.  
  223.             while ((ch = getc(_pw_fp)) != '\n' && ch != EOF)
  224.                 ;
  225.             continue;
  226.         }
  227.         _pw_passwd.pw_name = strsep(line, ":\n");
  228.         _pw_passwd.pw_passwd = strsep((char *)NULL, ":\n");
  229.         offset += _pw_passwd.pw_passwd - line;
  230.         if (!(cp = strsep((char *)NULL, ":\n")))
  231.             continue;
  232.         _pw_passwd.pw_uid = atoi(cp);
  233.         if (!(cp = strsep((char *)NULL, ":\n")))
  234.             continue;
  235.         _pw_passwd.pw_gid = atoi(cp);
  236.         _pw_passwd.pw_class = strsep((char *)NULL, ":\n");
  237.         if (!(cp = strsep((char *)NULL, ":\n")))
  238.             continue;
  239.         _pw_passwd.pw_change = atol(cp);
  240.         if (!(cp = strsep((char *)NULL, ":\n")))
  241.             continue;
  242.         _pw_passwd.pw_expire = atol(cp);
  243.         _pw_passwd.pw_gecos = strsep((char *)NULL, ":\n");
  244.         _pw_passwd.pw_dir = strsep((char *)NULL, ":\n");
  245.         _pw_passwd.pw_shell = strsep((char *)NULL, ":\n");
  246.         return(1);
  247.     }
  248.     /* NOTREACHED */
  249. }
  250.